home *** CD-ROM | disk | FTP | other *** search
- ;************************************************
- ;* function: int scale_fax_line(unsigned char *dest, unsigned char *src)
- ;* NOTE: The C code uses right rotates, this uses left rotates
- ;* cuz they are easier in assembly. The direction is not important
- ;* just as long as you are consistent.
- ;************************************************/
- vector_end_line: ;short jump way station
- jmp end_line
- public scale_fax_line
- scale_fax_line proc uses ds si di, dest: near ptr byte, src: near ptr byte
- ;int scale_fax_line(unsigned char *dest, unsigned char *src)
- ; {
- ; int y_repeat,x_repeat,i,bit;
- ; unsigned int accum;
- ; unsigned char byte;
- ; unsigned char *start;
- ; ROTATOR rotator;
-
- assume ds:nothing
- ;* get line repeat value and rotate to next */
- ; y_repeat = y_base + (y_rotator & 0x01);
- ; _ror(y_rotator);
- ; if (y_repeat)
- ; {
- mov ax,word ptr cs:y_rotator
- add ax,ax
- rcl word ptr cs:y_rotator+2,1
- adc ax,0
- mov word ptr cs:y_rotator,ax
- and ax,1
- add al,cs:y_base
- jnz line_ok
- jmp no_line
- line_ok:
- push bp
- push ax
- ;* if anything to do */
- mov si,ds ;large model data use lds and les
- mov es,si
- mov si,src
- mov di,dest
- ; rotator = x_rotator;
- mov bx,word ptr cs:x_rotator
- mov dx,word ptr cs:x_rotator+2
- ; for (i=source_width, accum=1, start=dest ; i > 0 ; i--, src++)
- mov bp,cs:source_width
- mov ah,1
- push di
- ; { ;* each byte in the source line */
- byte_loop:
- dec bp
- js vector_end_line
- lodsb
- ; if (*src)
- or al,al
- jz all_white
- ; { ;* if it has black bits */
- ; for (bit=8, byte=*src ; bit > 0 ; bit--)
- ; { ;* for each bit in the byte */
- ; x_repeat = x_base + (rotator & 1);
- ; _ror(rotator); ;* get repeat count and rotate */
- ; while (x_repeat--)
- ; { ;* for each repeat */
- ; accum <<= 1; ;* copy bit into accumulator */
- ; accum += ((byte & 0x80) != 0);
- ; if (accum & 0x100)
- ; { ;* output a byte and reset sentinel */
- ; *dest++ = (unsigned char) accum;
- ; accum = 1;
- ; }
- ; }
- ; byte <<= 1;
- mov cl,8
- bit_loop:
- xor ch,ch
- add bx,bx
- adc dx,dx
- adc ch,0
- add bl,ch
- add ch,cs:x_base
- or ch,ch
- jz bit_next
- bit_repeat:
- cmp al,80h
- cmc
- adc ah,ah
- jc bit_update
- repeat_next:
- dec ch
- jnz bit_repeat
- bit_next:
- add al,al
- dec cl
- jnz bit_loop
- jmp short byte_loop
- bit_update:
- xchg al,ah
- stosb
- xchg al,ah
- mov ah,1
- jmp short repeat_next
- ; }
- ; }
- ; else
- ; { ;* no black bits, just spin it out. */
- all_white:
- ;* how many repeats? */
- ; x_repeat = bit_repeat_count + ((rotator & 0xff) > bit_repeat_pattern);
- xor cx,cx
- cmp cs:bit_repeat_pattern,dh
- adc cx,cs:bit_repeat_count
- ;* rotate by 8 */
- ; rotator = (rotator << (PRECISION-8)) | (rotator >> 8);
- xchg bl,bh
- xchg bl,dl
- xchg bl,dh
- ;* do it */
- ; while (x_repeat--)
- ; {
- ; accum <<= 1;
- ; if (accum & 0x100)
- ; {
- ; *dest++ = (unsigned char) accum;
- ; accum = 1;
- ; }
- ; }
- jcxz byte_loop
- white_loop:
- add ax,ax
- jc white_update
- loop white_loop
- jmp byte_loop
- white_update:
- xchg al,ah
- stosb
- xchg al,ah
- mov ah,1
- loop white_loop
- jmp byte_loop
- ; }
- ; }
- ; if (accum > 1)
- ; { ;* handle fragment */
- ; while ((accum & 0x100) == 0)
- ; accum <<= 1;
- ; *dest++ = (unsigned char) accum;
- ; }
- end_line:
- cmp ah,1
- jbe no_fragment
- fragment_loop:
- add ah,ah
- jnc fragment_loop
- stosb
- no_fragment:
- ; while (dest < start + FAX_WIDTH)
- ; { ;* white out tail */
- ; *dest++ = 0;
- ; }
- ; }
- pop ax
- sub ax,di
- add ax,FAX_WIDTH
- jle no_tail
- mov cx,ax
- xor ax,ax
- shr cx,1
- rep stosw
- adc cx,0
- rep stosb
- no_tail:
- ; return y_repeat;
- pop ax
- pop bp
- no_line:
- ret
- ; }
- scale_fax_line endp
-